package com.seleniti.enpareja.android.ui.view;

import java.util.Objects;

import org.ioc.commons.flowcontrol.common.impl.ReceiverAdapter;
import org.ioc.commons.flowcontrol.logincontroller.IsLoggedUserInfoConsumer;
import org.ioc.commons.flowcontrol.logincontroller.LoginController;

import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.preference.SwitchPreference;

import com.seleniti.enpareja.android.R;
import com.seleniti.enpareja.android.control.entrypoint.EnParejaAndroid;
import com.seleniti.enpareja.controller.common.domain.LoggedUserInfo;
import com.seleniti.enpareja.controller.control.controller.LoginFailedCause;
import com.seleniti.enpareja.controller.control.controller.LoginParams;
import com.seleniti.enpareja.controller.control.factory.ClientFactory;
import com.seleniti.enpareja.controller.model.integration.database.domain.Settings;
import com.seleniti.enpareja.controller.model.integration.database.domain.User;

public class AppSettingsActivity extends Activity implements IsLoggedUserInfoConsumer<LoggedUserInfo> {

	public enum ResultCode {
		ACTIVITY_DOESNT_REQUIRES_RESET, ACTIVITY_REQUIRES_RESET;
	}

	public static class SettingsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener,
			IsLoggedUserInfoConsumer<LoggedUserInfo> {

		private ClientFactory clientFactory;
		private LoginController<LoggedUserInfo, LoginFailedCause, LoginParams, String> loginController;
		private LoggedUserInfo loggedUserInfo;

		@Override
		public void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);

			// Load the preferences from an XML resource
			addPreferencesFromResource(R.xml.prefs);
		}

		@Override
		public void onResume() {
			super.onResume();
			getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
		}

		@Override
		public void onPause() {
			super.onPause();
			getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
		}

		@Override
		public void onActivityCreated(Bundle savedInstanceState) {
			super.onActivityCreated(savedInstanceState);
			this.clientFactory = ((EnParejaAndroid) getActivity().getApplication()).getClientFactory();

			this.loginController = this.clientFactory.getLoginController();

			this.loginController.requiresLoggedUserInfo(this);
		}

		@Override
		public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {

			switch (key) {
			case "isDebug":
				// Preference debugPref = findPreference(key);
				// Set summary to be the user-description for the selected value
				EnParejaAndroid app = (EnParejaAndroid) this.getActivity().getApplication();
				app.setWebSiteUrl();
				getActivity().setResult(ResultCode.ACTIVITY_REQUIRES_RESET.ordinal());
				break;
			case "notifyChanges":
				getActivity().setResult(ResultCode.ACTIVITY_DOESNT_REQUIRES_RESET.ordinal());

				if (loggedUserInfo.isLogged()) {
					clientFactory.getServiceManager().serviceFactory().userService().find(loggedUserInfo.getUserId()).caller(this)
							.to(new ReceiverAdapter<User>() {

								@Override
								public void success(User result) {
									Settings s = result.getSettings();

									if (s == null) {
										s = new Settings();
										s.setOfThisUser(result);

										result.setSettings(s);
									}

									boolean notifyChanges = sharedPreferences.getBoolean(key, true);
									s.setNotifyMeWhenChanges(notifyChanges);

									clientFactory.getServiceManager().serviceFactory().userService()
											.save(result, false).caller(SettingsFragment.this);
								}
							});
				}
				break;
			default:
				getActivity().setResult(ResultCode.ACTIVITY_DOESNT_REQUIRES_RESET.ordinal());
				break;
			}

		}

		@Override
		public void onLoggedUserInfoNotReadyYet() {
			/*
			 * Nothing to do
			 */
		}

		@Override
		public void onLoggedUserInfoDataReady() {
			this.setLoggedUserInfo(this.clientFactory.getLoginController().getLoggedUserInfo());
		}

		@Override
		public void onLoggedUserInfoDataUpdated(LoggedUserInfo loggedUserInfo) {
			this.setLoggedUserInfo(loggedUserInfo);
		}

		public void setLoggedUserInfo(LoggedUserInfo loggedUserInfo) {
			boolean changed = !Objects.equals(loggedUserInfo, this.loggedUserInfo);
			this.loggedUserInfo = loggedUserInfo;

			SwitchPreference notifyChanges = (SwitchPreference) getPreferenceScreen().findPreference("notifyChanges");

			notifyChanges.setEnabled(this.loggedUserInfo != null && this.loggedUserInfo.isLogged());

			if (changed && notifyChanges.isEnabled()) {
				clientFactory.getServiceManager().serviceFactory().userService().find(loggedUserInfo.getUserId()).caller(this)
						.to(new ReceiverAdapter<User>() {

							@Override
							public void success(User result) {
								Settings s = result.getSettings();

								if (s == null) {
									s = new Settings();
									s.setOfThisUser(result);

									result.setSettings(s);
								}

								SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();

								Editor edit = sharedPreferences.edit();
								edit.putBoolean("notifyChanges", s.isNotifyMeWhenChanges());

								edit.commit();
							}
						});

			}
		}
	}

	private ClientFactory clientFactory;
	private LoginController<LoggedUserInfo, LoginFailedCause, LoginParams, String> loginController;
	private LoggedUserInfo loggedUserInfo;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.clientFactory = ((EnParejaAndroid) getApplication()).getClientFactory();
		this.loginController = clientFactory.getLoginController();

		// Display the fragment as the main content.
		getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
	}

	@Override
	protected void onResume() {
		super.onResume();

		this.loginController.requiresLoggedUserInfo(this);
	}

	@Override
	public void onBackPressed() {
		super.onBackPressed();

		clientFactory.getPlaceController().forThisObject(this).notifyPlaceChanged();
	}

	@Override
	public void onLoggedUserInfoNotReadyYet() {
		/*
		 * Nothing to do
		 */
	}

	@Override
	public void onLoggedUserInfoDataReady() {
		this.loggedUserInfo = this.clientFactory.getLoginController().getLoggedUserInfo();
	}

	@Override
	public void onLoggedUserInfoDataUpdated(LoggedUserInfo loggedUserInfo) {
		this.loggedUserInfo = loggedUserInfo;
	}
}